package ch.epfl.lara.matcheck;

object Options extends Enumeration {

  type ProgOption  = Value
  type Description = String
  
  
  val DEBUG          = Value("-debug")
  val WARNINGS       = Value("-warnings")
  val PERFORMANCE    = Value("-performance")
  val VERBOSE        = Value("-verbose")
  val V              = Value("-v")
  val NOCHECKS       = Value("-nochecks")
  val HELP           = Value("-help")
  val NOCOMPLETE     = Value("-nocomplete")
  val DISJOINT       = Value("-disjoint")
  val REACHABLE      = Value("-reachable")
  val ALL            = Value("-all")
  val NOSPEC         = Value("-nospec")
  val STATS          = Value("-stats")
  
  
  import scala.collection.mutable.HashMap;

  val string2option = new HashMap[String, ProgOption]
  
  
  string2option += "-debug"               -> DEBUG
  string2option += "-warnings"            -> WARNINGS
  string2option += "-verbose"             -> VERBOSE
  string2option += "-v"                   -> V
  string2option += "-nochecks"            -> NOCHECKS
  string2option += "-performance"         -> PERFORMANCE
  string2option += "-stats"         -> STATS
  // prompt usage
  string2option += "-help"                -> HELP
  
  // check PM properties
  string2option += "-nocomplete"          -> NOCOMPLETE
  string2option += "-disjoint"            -> DISJOINT
  string2option += "-reachable"           -> REACHABLE
  string2option += "-all"                 -> ALL
  
  // verify specification
  string2option += "-nospec"              -> NOSPEC
  
  import scala.collection.immutable.ListMap;
  var option2description: Map[ProgOption,Description] = new ListMap[ProgOption,Description].empty
  option2description = option2description.update(NOSPEC, "disable verification of specification (domain, pre/postcondition and invariants)")
  option2description = option2description.update(NOCOMPLETE,"disable completeness check (default checked property)")
  option2description = option2description.update(DISJOINT, "enable disjointness check")
  option2description = option2description.update(REACHABLE, "enable redundancy check")
  option2description = option2description.update(ALL, "check completeness, disjointness and reachability")
  
  option2description = option2description.update(NOCHECKS, "disable verification and prompt the syntax Tree. It overrides any other check option")
  
  option2description = option2description.update(VERBOSE, "prompt messages about what matcheck is doing")
  option2description = option2description.update(V, "verbose mode")

  option2description = option2description.update(PERFORMANCE, "prompt measured time consumed by each phase")
  option2description = option2description.update(STATS, "prompt some statistic of the analyzed file")
  
  option2description = option2description.update(DEBUG, "prompt debug information (useful for bug fixing)")
  option2description = option2description.update(WARNINGS, "prompt warning messages. Use this option if the application crash")
 
  option2description = option2description.update(HELP, "display this list of options")
    
    
  
  def apply(arg: String): Unit = string2option.get(arg) match {
    case None         =>
      Report.cleanFail("matcheck: error: don't know what to do with option '"+arg+"'")
      
      
    case Some(option) => this(option)
  }
  
  
  def apply(option: ProgOption): Unit = option match {
    case DEBUG          => Config.DEBUG          = true
    case WARNINGS       => Config.WARNINGS       = true
    case VERBOSE | V    => Config.VERBOSE        = true
    case PERFORMANCE    => Config.PERFORMANCE    = true
    case STATS          => Config.STATS          = true
    case NOCOMPLETE     => Config.COMPLETE       = false
    case DISJOINT       => Config.DISJOINT       = true
    case REACHABLE      => Config.REACHABLE      = true
    case ALL            =>
                           Config.COMPLETE = true
                           Config.DISJOINT = true
                           Config.REACHABLE= true
    case NOCHECKS       => Config.NOCHECKS = true
    case NOSPEC         => Config.NOSPEC   = true
    case HELP           => Config.HELP     = true
  }
  
  
  def getName(option: ProgOption): String = option.toString
  
}
